/**
 * TO BE DETERMINED
 */
package org.eichar.client.shared;

import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * Encapsulates the concept of a language.
 * 
 * @author Jesse
 */
public class Language {

    private final String code;

    final Set/* <Word> */identifiers = new HashSet/* <Word> */();

    private static final Map/* <String, Language> */languages = new HashMap/*
                                                                             * <String,
                                                                             * Language>
                                                                             */();

    private Language(final String code) {
        this.code = code;
    }

    /**
     * Factory method for obtaining languages. Two requests with the same code
     * will return the same instance. If the identifiers are different then the
     * two identifiers will be combined in the instance.
     * 
     * @param code
     *            language code. For example: en, de, en-us, etc...
     * @param identifier
     * @return
     */
    public static Language getLanguage(String code, Word identifier) {
        Set tmp = new HashSet();
        tmp.add(identifier);
        return getLanguage(code, tmp);
    }

    /**
     * Factory method for obtaining languages. Two requests with the same code
     * will return the same instance. If the identifiers are different then the
     * two identifiers will be combined in the instance.
     * 
     * @param code
     *            language code. For example: en, de, en-us, etc...
     * @param identifier
     * @return
     */
    public static synchronized Language getLanguage(String code,
            Set/* <Word> */identifiers) {
        Language language = (Language) languages.get(code);
        if (language == null) {
            language = new Language(code);
            languages.put(code, language);
        }

        language.identifiers.addAll(identifiers);
        return language;
    }

    /**
     * @return the code
     */
    public final String getCode() {
        return this.code;
    }

    /**
     * @return the identifiers as an umodifiable set.
     */
    public final Set/* <Word> */getIdentifiers() {
        return new UnmodifiableSet(this.identifiers);
    }

    /* @Override */
    public String toString() {
        StringBuffer builder = new StringBuffer();
        builder.append(code);
        builder.append(':');
        builder.append(identifiers.toString());
        return builder.toString();
    }

    /**
     * Returns the language.
     * 
     * @param languageCode
     * @return
     */
    public static Language getLanguage(String languageCode) {
        return getLanguage(languageCode, Collections.EMPTY_SET);
    }

}
